# -*- coding: UTF-8 -*-
"""
@Time:2022/4/29 9:46
@File:article.py
@Author:常雷
@Software:PyCharm
"""
import datetime
from rest_framework.response import Response
from django.shortcuts import render, HttpResponse
from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.generics import CreateAPIView, ListAPIView, RetrieveAPIView
from palyWordDackend import models
from django.forms import model_to_dict
from rest_framework import status
from django.db.models import F
import uuid
import requests
import re


class CreateArticle(APIView):
    def post(self, request, *args, **kwargs):
        print(request.data)
        tag_name = request.data.get('tag_name')
        category_name = request.data.get('category_name')
        title = request.data.get('title')
        desc = request.data.get('desc')
        content = request.data.get('content')
        token = request.data.get('token')
        if content == '':
            return Response({'code': 201, 'smg': '没有内容'})
        tag_name_list = tag_name.split(' ')
        # 标签
        tag_id_list = []
        for tag_n in tag_name_list:
            if tag_n and len(tag_n) < 10:
                exists = models.Tag.objects.filter(name=tag_n)

                if not exists.exists():
                    tag_nam = models.Tag.objects.create(name=tag_n, hot_count=1)
                    # print(tag_nam)  # 吐槽
                    tag_id_list.append(list(models.Tag.objects.filter(name=tag_nam).values('id'))[0]['id'])
                else:
                    # data['username']=exists_1.values('username')
                    # 存在更新 openid可以设置,可以不设置
                    exists.update(hot_count=F('hot_count') + 1)
                    tag_id_list.append(list(exists.values('id'))[0]['id'])
        print(tag_id_list)
        # 分类
        if category_name == '':
            category_name = '未分类'
        exists = models.Category.objects.filter(name=category_name)
        if not exists.exists():
            category_n = models.Category.objects.create(name=category_name, hot_count=1)
            category_id = list(models.Category.objects.filter(name=category_name).values('id').values('id'))[0]['id']
            # category_obj = models.Category.objects.filter(name=category_name).first()
        else:
            # data['username']=exists_1.values('username')
            # 存在更新 openid可以设置,可以不设置
            exists.update(hot_count=F('hot_count') + 1)
            category_id = list(exists.values('id'))[0]['id']
            # category_obj = exists.filter(name=category_name).first()
        # print('category_obj', category_obj)
        # print('category_id', category_id)
        # 生成题目和简介
        if not title:
            title = re.split(r'\W+', re.sub(r'<.*?>', '', content))[0]
        if not desc:
            desc = re.split(r'\n', re.sub(r'<.*?>', '', content))[0]

        # 找到作者
        # exists = models.UserInfo.objects.filter(token=token).first().values('id', 'username')
        exists = models.UserInfo.objects.filter(token=token)
        if not exists.exists():
            return Response({'code': 201, 'smg': '没有作者'})
        user_obj = exists.first()
        print('user_obj', user_obj)

        # 文章保存到数据库
        article_obj = models.Article.objects.create(
            title=title,
            desc=desc,
            category_id=category_id,
            content=content,
            user=user_obj,
        )
        article_obj_list = []
        for i in tag_id_list:
            # 生成对象,添加到列表
            article_obj_list.append(models.Article2Tag(article=article_obj, tag_id=i))
        # 批量插入数据 .bulk_create()
        models.Article2Tag.objects.bulk_create(article_obj_list)
        return Response(status=status.HTTP_200_OK)


class ArticlePreviewModlSerializer(serializers.ModelSerializer):
    # images = serializers.SerializerMethodField()
    # create_date = serializers.SerializerMethodField()
    # def get_create_date(self,obj):
    #     return obj.create_date.strftime("%Y-%m-%d %H:%M")
    # create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M")

    user = serializers.SerializerMethodField()
    category = serializers.SerializerMethodField()

    viewer = serializers.SerializerMethodField()

    comment = serializers.SerializerMethodField()
    tags = serializers.SerializerMethodField()

    class Meta:
        model = models.Article
        fields = "__all__"
        # exclude = ['cover']

    # def get_images(self, obj):
    #     # 找到当前新闻的所有图片对象
    #     detail_queryset = models.ArticleDetail.objects.filter(Article=obj)
    #     # return [row.cos_path for row in detail_queryset]
    #     # return [{"id":row.id, "path":row.cos_path} for row in detail_queryset]
    #     return [model_to_dict(row, ['id', 'cos_path']) for row in detail_queryset]

    def get_create_date(self, obj):
        return obj.create_date.strftime("%Y-%m-%d %H:%M")

    def get_user(self, obj):
        # model_to_dict fields:需要字段列表,exclude:不需要字段
        return model_to_dict(obj.user, fields=['id', 'username', 'avatar'])

    def get_category(self, obj):
        if obj.category:
            return model_to_dict(obj.category, fields=['id', 'name'])

    def get_tags(self, obj):
        tag_queryset = models.Article2Tag.objects.filter(article=obj).order_by('-id')
        queryset = models.Article2Tag.objects.filter(article=obj.id)
        context = {
            'count': queryset.count(),
            'result': [model_to_dict(row.tag, ['name', 'hot_count']) for row in tag_queryset]
        }
        return context

    def get_viewer(self, obj):
        viewer_queryset = models.ViewerRecord.objects.filter(news=obj).order_by('-id')[0:10]
        queryset = models.ViewerRecord.objects.filter(news=obj.id)
        context = {
            'count': queryset.count(),
            'result': [model_to_dict(row.user, ['username', 'avatar']) for row in viewer_queryset]
        }
        return context

    #
    def get_comment(self, obj):
        """
        # 获取所有的1级评论。再給每个1级评论获取一个二级评论。
        :param obj:
        :return:
        """
        # 1 获取所有的1级评论
        first_queryset = models.Comment.objects.filter(article=obj, depth=1).order_by('id')[0:10].values(
            'id',
            'content',
            'depth',
            'user__username',
            'user__avatar',
            'comment_time'
        )
        first_id_list = [item['id'] for item in first_queryset]
        # 2 获取所有的2级评论
        # second_queryset = models.Comment.objects.filter(Article=obj, depth=2)
        # 2 获取所有一级评论的2级评论
        # second_queryset = models.Comment.objects.filter(Article=obj, depth=2, reply_id__in=first_id_list)
        # 2 获取所有一级评论的2级评论(每个二级评论只取一条,最新或者最热)
        from django.db.models import Max
        result = models.Comment.objects.filter(article=obj, depth=2, reply_id__in=first_id_list).values(
            'reply_id').annotate(max_id=Max('id'))
        # print(result)<QuerySet [{'reply_id': 1, 'max_id': 5}, {'reply_id': 8, 'max_id': 12}]>
        second_id_list = [item['max_id'] for item in result]
        second_queryset = models.Comment.objects.filter(id__in=second_id_list).values(
            'id',
            'content',
            'depth',
            'user__username',
            'user__avatar',
            'comment_time',
            'reply_id',
            'reply__user__username'
        )
        # print(second_queryset)
        import collections
        first_dict = collections.OrderedDict()
        for item in first_queryset:
            item['comment_time'] = item['comment_time'].strftime('%Y-%m-%d %H:%M')
            first_dict[item['id']] = item
        for node in second_queryset:
            node['comment_time'] = node['comment_time'].strftime('%Y-%m-%d %H:%M')
            first_dict[node['reply_id']]['child'] = [node, ]
        return first_dict.values()


class ArticlePreview(RetrieveAPIView):
    queryset = models.Article.objects
    serializer_class = ArticlePreviewModlSerializer

    def post(self, request, *args, **kwargs):
        token = request.data.get('token')
        articleId = request.data.get('articleId')
        # print(request.data) # {'token': '0a229e5d-d13b-44aa-be5e-b97685c04ef0', 'articleId': '8'}
        user_id = models.UserInfo.objects.filter(token=token).values('id')
        models.ViewerRecord.objects.create(news_id=articleId, user_id=user_id)
        return Response(status=200)


# 赞踩事务
class UpAndDownView(APIView):
    def post(self, request, *args, **kwargs):
        data = {'code': 200, 'mas': ''}
        is_up = request.data.get('is_up')
        token = request.data.get('token')
        articleId = request.data.get('articleId')
        if not token:
            data['code'] += 1
            data['mas'] += '用户未登录\n'
        elif not articleId:
            data['code'] += 10
            data['mas'] += ' 没有选择文章\n'
        else:
            user_id = models.UserInfo.objects.filter(token=token).values('id').first()['id']
            # user_id=models.UserInfo.objects.filter(token=token).values('id')
            print(user_id)
            if models.NewsFavorRecord.objects.filter(user=user_id, news=articleId):
                data['code'] += 100
                data['mas'] += ' 您已经点过了'
            else:
                is_up = int(is_up)
                models.NewsFavorRecord.objects.create(user_id=user_id, news_id=articleId)
                models.UpAndDown.objects.create(user_id=user_id, article_id=articleId, is_up=is_up)
                article_obj = models.Article.objects.filter(pk=articleId)
                up_num = article_obj.values('up_num').first()['up_num']
                down_num = article_obj.values('down_num').first()['down_num']
                # article_obj_dict = model_to_dict(article_obj)
                if is_up:
                    up_num += 1
                    # article_obj.up_num = article_obj.first().values('up_num') + 1
                    # article_obj.up_num = article_obj_dict.up_num + 1
                else:
                    down_num += 1
                    # article_obj.down_num = article_obj_dict.down_num + 1
                # 保存
                models.Article.objects.filter(pk=articleId).update(up_num=up_num, down_num=down_num)
        print(is_up, token, articleId)
        return Response(data, status=200)


'''获取根评论的所有子评论'''
"""
"child": [
            {
                "id": 5,
                "content": "1-2",
                "user__username": "lao胡小号-6",
                "user__avatar": "http://m.imeitou.com/uploads/allimg/220327/5-22032G63939.jpg",
                "create_date": "2022-04-27 07:38",
                "reply_id": 1,
                "reply__user__username": "lei"
            }
    ]
"""


class CommentModelSerializer(serializers.ModelSerializer):
    comment_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M")
    # CharField中source参数跨表查询
    user__username = serializers.CharField(source='user.username')
    user__avatar = serializers.CharField(source='user.avatar')
    # reply_user = serializers.SerializerMethodField()
    reply_id = serializers.CharField(source='reply.id')
    reply__user__username = serializers.CharField(source='reply.user.username')

    class Meta:
        model = models.Comment
        # fields = "__all__"
        exclude = ['Article', 'user', 'reply', 'root']

    # def get_user(self, obj):
    #     # model_to_dict fields:需要字段列表,exclude:不需要字段
    #     return model_to_dict(obj.user, fields=['id', 'username', 'avatar'])
    #
    # def get_reply_user(self, obj):
    #     return model_to_dict(obj.user, fields=['id', 'username'])


class CreateCommentModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Comment
        # fields = "__all__"
        exclude = ['user', 'comment_time', 'favor_count']


class CommentView(APIView):
    def get(self, request, *args, **kwargs):
        root_id = request.query_params.get('root')

        # 1. 获取根评论的所有子评论
        node_queryset = models.Comment.objects.filter(root_id=root_id).order_by('id')
        # 2. 序列化
        ser = CommentModelSerializer(instance=node_queryset, many=True)

        return Response(ser.data, status=status.HTTP_200_OK)

    def post(self, request, *args, **kwargs):
        print('request.data;', request.data)
        if not request.data.get('token'):
            return Response({'code': 201, 'msg': '用户未登录'}, status=status.HTTP_200_OK)
        user_id = models.UserInfo.objects.filter(token=request.data.get('token')).values('id').first()['id']
        data = {
            'article': request.data.get('news'),
            'depth': request.data.get('depth'),
            'content': request.data.get('content'),
            'user': user_id,
            'reply': request.data.get('reply'),
            'parent': request.data.get('root'),
        }
        # 1.进行数据校验 Article/depth/reply/content/root
        ser = CreateCommentModelSerializer(data=data)
        # print('ser:', ser, 'ser.is_valid():', ser.is_valid())
        if ser.is_valid():
            # 保存到数据库
            ser.save(user_id=1)
            # 对新增到数据值进行序列化
            print(ser.data)
            # 更新其他关联表
            Article_id = ser.data.get('Article')
            models.Article.objects.filter(id=Article_id).update(comment_num=F('comment_num') + 1)
            return Response(ser.data, status=status.HTTP_201_CREATED)
        return Response(ser.data, status=status.HTTP_400_BAD_REQUEST)
        # 2.校验通过，保存到数据库
        # 3.将保存到数据库的数据再返回给小程序页面(小程序需要在页面上进行展示)

